package com.box.service.impl;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.box.entity.WXResult;
import com.box.entity.wx.WxOrderOther;
import com.box.entity.wx.WxOrderResult;
import com.box.service.WeiXinService;
import com.box.utils.DateUtils;
import com.box.utils.HttpClientUtil;
import com.box.utils.Md5Util;
import com.box.utils.ResponseResult;
import com.box.utils.SessionUtils;
import com.box.utils.StringUtils;
import com.box.utils.XmlUtil;
import com.box.utils.wx.WxUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;

import net.sf.json.JSONArray;


/**   
*    
* 项目名称：MyBox   
* 类名称：WeiXinServiceImpl   
* 类描述：   微信接口实现类
* 创建人：君无邪   
* 创建时间：2019年10月5日 下午3:41:41   
* 修改人：君无邪 
* 修改时间：2019年10月5日 下午3:41:41   
* 修改备注：  https://www.java214.com 
* @version    
*    
*/ 
@Service
public class WeiXinServiceImpl implements WeiXinService {
	
	@Value("${appid}")
	private String appid;//公众号APPID
	
	@Value("${mch_id}")//商户号
	private String mch_id;
	
	@Value("${device_info}")//设备号
	private String device_info;
	
	@Value("${url}")
	private String url;//支付请求地址
	
	@Value("${notify_url}")
	private String notify_url;//可访问的回调地址
	
	@Value("${key}")
	private String key;//商户API秘钥
	
	@Value("${QueryOrder}")
	private String QueryOrder;
	


	public Map<String,Object> LoadImage(HttpServletRequest request,HttpServletResponse response) throws Exception {
		String orderNo=DateUtils.getCurrentDateStr(); // 生成订单号
		
		Map<String, Object> result=new HashMap<String, Object>();
		
		Map<String,Object> map=new HashMap<String,Object>();
		//商户订单号，商户网站订单系统中唯一订单号，必填
		//付款金额，必填
String	 total_amount = new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");
		//订单名称，必填
String		 subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");
		//商品描述，可空
String		 body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");
		map.put("appid", appid); // 公众账号ID
		System.out.println(appid+"............获取的APPID.............."); 
		map.put("mch_id", mch_id); // 商户号
		map.put("device_info", device_info); // 设备号
		map.put("notify_url", notify_url); // 异步通知地址
		map.put("trade_type", "NATIVE"); // 交易类型
		map.put("out_trade_no", orderNo); // 商户订单号订单号之类可变更
		map.put("body",  body); // 商品描述
		map.put("total_fee",total_amount); // 标价金额
		// map.put("spbill_create_ip", getRemortIP(request)); // 终端IP
		map.put("spbill_create_ip", "127.0.0.1"); // 终端IP
		map.put("nonce_str", StringUtils.getRandomString(30)); // 随机字符串
		map.put("sign", getSign(map)); // 签名
		String xml=XmlUtil.genXml(map); 
		System.out.println(xml);
		InputStream in=HttpClientUtil.sendXMLDataByPost(url, xml).getEntity().getContent(); // 发现xml消息
		String code_url=getElementValue(in,"code_url"); // 获取二维码地址
		MultiFormatWriter multiFormatWriter = new MultiFormatWriter();  
	    Map hints = new HashMap();  
	    BitMatrix bitMatrix = null;
	     
	         //输出二维码图片流  
	         try {
	        	  bitMatrix=multiFormatWriter.encode(code_url, BarcodeFormat.QR_CODE, 250, 250,hints);  
	        	    BufferedImage image = toBufferedImage(bitMatrix);  
	        
	 	         
	 	         //因为返回的图片地址是true所以在开发上有些蛋疼。放到map也行,list也行，只要不是其余不知道的类型就行
	
	 
	 	result.put("imageUrl", ImageIO.write(image, "png", response.getOutputStream()));
	 	result.put("total_fee",  total_amount);
	 	result.put("body", body);
	 	result.put("out_trade_no", orderNo);
	 	result.put("subject", subject);
	 	
	         } catch (Exception e) {
				// TODO: handle exception
				System.out.println("如果二维码图片出来了，会抛出格式错误不用管这个错误"+e);
			}
	
	       

	         		return result;
	}

	public String PcPay(HttpServletRequest request,HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	/**
     * 获取本机IP地址
     * @return IP
     */
	private static String getRemortIP(HttpServletRequest request) {  
        if (request.getHeader("x-forwarded-for") == null) {  
            return request.getRemoteAddr();  
        }  
        return request.getHeader("x-forwarded-for");  
    }
	
	/**
     * 微信支付签名算法sign
     */
	 private String getSign(Map<String,Object> map) {
	        StringBuffer sb = new StringBuffer();
	        String[] keyArr = (String[]) map.keySet().toArray(new String[map.keySet().size()]);//获取map中的key转为array
	        Arrays.sort(keyArr);//对array排序
	        for (int i = 0, size = keyArr.length; i < size; ++i) {
	            if ("sign".equals(keyArr[i])) {
	                continue;
	            }
	            sb.append(keyArr[i] + "=" + map.get(keyArr[i]) + "&");
	        }
	        sb.append("key=" + key);
	        String sign = Md5Util.string2MD5(sb.toString());
	        return sign;
	    }
    
    /**
   	 * 通过返回IO流获取支付地址
   	 * @param in
   	 * @return
   	 */
	 private String getElementValue(InputStream in,String key){
			SAXReader reader = new SAXReader();
	        Document document=null;
			try {
				document = reader.read(in);
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        Element root = document.getRootElement();
	        List<Element> childElements = root.elements();
	        for (Element child : childElements) {
	        	System.out.println(child.getName()+":"+child.getStringValue());
	        	if(key.equals(child.getName())){
	        		return child.getStringValue();
	        	}
	        }
	        return null;
		}
   	
   	
   	/** 
	   * 类型转换 
	   * @author chenp 
	   * @param matrix 
	   * @return 
	   */  
	 public static BufferedImage toBufferedImage(BitMatrix matrix) {  
    int width = matrix.getWidth();  
    int height = matrix.getHeight();  
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);  
    for (int x = 0; x < width; x++) {  
        for (int y = 0; y < height; y++) {  
            image.setRGB(x, y, matrix.get(x, y) == true ? 0xff000000 : 0xFFFFFFFF);  
        }  
    }  
    return image;  
	 }

	 /**
	  * 异步请求处理
	  */
	public String PayNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//读取参数    
        InputStream inputStream ;    
        StringBuffer sb = new StringBuffer();    
        inputStream =  request.getInputStream();    
        String s ;    
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));    
        while ((s = in.readLine()) != null){    
            sb.append(s);    
        }    
        in.close();    
        inputStream.close();  
        System.out.println("sb:"+sb.toString());
        
        //解析xml成map    
        Map<String, String> m = new HashMap<String, String>();    
        try {
			m = XmlUtil.doXMLParse(sb.toString());
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}    
            
        //过滤空 设置 TreeMap    
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();          
        Iterator<String> it = m.keySet().iterator();    
        while (it.hasNext()) {    
            String parameter = it.next();    
            String parameterValue = m.get(parameter);    
                
            String v = "";    
            if(null != parameterValue) {    
                v = parameterValue.trim();    
            } 
            packageParams.put(parameter, v);    
        }  
        
        // 微信支付的API密钥    

        
        if(isTenpaySign("UTF-8", packageParams, key)){ // 验证通过
        	if("SUCCESS".equals((String)packageParams.get("result_code"))){  
        		return "验证通过";
        	}else{
        		return "支付失败";
        	}
        }else{
        	return "验证未通过";
        }
	}
	
	/**  
     * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。  
     * @return boolean  
     */    
    public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {    
        StringBuffer sb = new StringBuffer();    
        Set es = packageParams.entrySet();    
        Iterator it = es.iterator();    
        while(it.hasNext()) {    
            Map.Entry entry = (Map.Entry)it.next();    
            String k = (String)entry.getKey();    
            String v = (String)entry.getValue();    
            if(!"sign".equals(k) && null != v && !"".equals(v)) {    
                sb.append(k + "=" + v + "&");    
            }    
        }    
        sb.append("key=" + API_KEY);    
            
        //算出摘要    
        String mysign = Md5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();    
        String tenpaySign = ((String)packageParams.get("sign")).toLowerCase();    
            
        return tenpaySign.equals(mysign);    
    }
    
    //返回同步跳转
	public ResponseResult LoadPayStatus(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
		Integer result=0;
		result++;
		Integer data=0;
		try {
			Thread.sleep(1000);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		if(result==10){
			data=1;
		}
		System.out.println("result"+result);
		System.out.println("data"+data);
	
	

		ResponseResult build = ResponseResult.build(0, "ok", data);
		return build;
	}  
	
	


	public String  getOrderListByOrderNum(String orderNum) throws Exception {
		// TODO Auto-generated method stub
		
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("appid", appid); // 公众账号ID
		map.put("mch_id", mch_id); // 商户号
		//map.put("transaction_id", "4200000087201804105653326283"); // 微信订单号
		 map.put("out_trade_no", orderNum); // 商户订单号
		map.put("mch_id", mch_id); // 商户号
		map.put("nonce_str", StringUtils.getRandomString(30)); // 随机字符串
		map.put("sign", getSign(map)); // 签名
		String xml=XmlUtil.genXml(map); 
		System.out.println(xml);
		InputStream in=HttpClientUtil.sendXMLDataByPost(QueryOrder, xml).getEntity().getContent(); // 发送xml消息
		Map<String, String> resmap = WxUtils.getElementValue(in);
		for (String key : resmap.keySet()) {
			System.out.println("key:"+key+",value:"+map.get(key));
			
		}
		 WxOrderOther wo=new WxOrderOther();
	



return xml;
	
	}

	public void LoadImageTwo(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// TODO Auto-generated method stub
String orderNo=DateUtils.getCurrentDateStr(); // 生成订单号
		
		
		Map<String,Object> map=new HashMap<String,Object>();
		//商户订单号，商户网站订单系统中唯一订单号，必填
		//付款金额，必填
String	 total_amount = new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");
		//订单名称，必填
String		 subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");
		//商品描述，可空
String		 body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");
		map.put("appid", appid); // 公众账号ID
		System.out.println(appid+"............获取的APPID.............."); 
		map.put("mch_id", mch_id); // 商户号
		map.put("device_info", device_info); // 设备号
		map.put("notify_url", notify_url); // 异步通知地址
		map.put("trade_type", "NATIVE"); // 交易类型
		map.put("out_trade_no", orderNo); // 商户订单号订单号之类可变更
		map.put("body",  body); // 商品描述
		map.put("total_fee",total_amount); // 标价金额
		// map.put("spbill_create_ip", getRemortIP(request)); // 终端IP
		map.put("spbill_create_ip", "127.0.0.1"); // 终端IP
		map.put("nonce_str", StringUtils.getRandomString(30)); // 随机字符串
		map.put("sign", getSign(map)); // 签名
		String xml=XmlUtil.genXml(map); 
		System.out.println(xml);
		InputStream in=HttpClientUtil.sendXMLDataByPost(url, xml).getEntity().getContent(); // 发现xml消息
		String code_url=getElementValue(in,"code_url"); // 获取二维码地址
		MultiFormatWriter multiFormatWriter = new MultiFormatWriter();  
	    Map hints = new HashMap();  
	    BitMatrix bitMatrix = null;
	     
	         //输出二维码图片流  
	         try {
	        	  bitMatrix=multiFormatWriter.encode(code_url, BarcodeFormat.QR_CODE, 250, 250,hints);  
	        	    BufferedImage image = toBufferedImage(bitMatrix);  
	        
	 	         
	 	         //因为返回的图片地址是true所以在开发上有些蛋疼。放到map也行,list也行，只要不是其余不知道的类型就行
	
	 
	 	 ImageIO.write(image, "JPEG", response.getOutputStream());
	 
	         } catch (Exception e) {
				// TODO: handle exception
				System.out.println("如果二维码图片出来了，会抛出格式错误不用管这个错误"+e);
			}
	
	       

	         		
		
	}
}
